package com.hhkj.admin.bank.common.component.supplier;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hhkj.admin.bank.common.cont.RuleConst;
import com.hhkj.admin.bank.domain.BankRule;
import com.hhkj.admin.bank.model.dopo.BankRuleDo;
import com.hhkj.admin.bank.model.dopo.BankRulePo;
import com.hhkj.admin.bank.model.res.BankRuleRes;
import com.hhkj.admin.bank.service.base.BankRuleService;
import com.hhkj.admin.bank.service.extend.BankRuleExtendService;
import com.hhkj.admin.course.domain.Course;
import com.hhkj.admin.course.service.base.CourseService;
import com.hhkj.admin.course.service.extend.CourseExtendService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * BankRuleSupplier
 *
 * @author HHKJ-SERVER-ZJ
 * @since 2023/6/8 15:32
 */
@Component
public class RuleSupplier
{
    @Autowired
    private BankRuleService service;
    @Autowired
    private BankRuleExtendService extendService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private CourseExtendService courseExtendService;

    /**
     * 补充科目规则配置信息
     *
     * @param res 类别配置信息
     */
    public void supplyCourseChildren(BankRuleRes res)
    {
        // 如果是指定科目规则，获取科目规则信息列表
        List<BankRulePo> childrenPo = extendService.listPoByParentId(res.getId());
        List<BankRuleRes> childrenRes = BeanUtil.copyToList(childrenPo, BankRuleRes.class);
        Set<Long> childrenCourseIdSet = childrenRes.stream()
                .map(BankRule::getCourseId)
                .collect(Collectors.toSet());
        // 获取对应的科目列表，查看是否完整，如果没有的话添加未配置的科目配置信息
        List<Course> courseChildren
                = courseExtendService.listByParentId(res.getCourseParentId());
        for (Course child : courseChildren) {
            if (!childrenCourseIdSet.contains(child.getId())) {
                BankRuleRes undefinedRule = new BankRuleRes(child.getId(), child.getName());
                childrenRes.add(undefinedRule);
            }
        }
        childrenRes.sort(Comparator.comparing(BankRule::getCourseId));
        res.setChildren(childrenRes);
    }

    /**
     * 补充科目规则配置信息
     *
     * @param res 类别配置信息
     */
    public void supplyChildren(BankRuleRes res)
    {
        // 如果是指定科目规则，获取科目规则信息列表
        if (res.hasCourseChildrenRule()) {
            supplyCourseChildren(res);
        }
    }

    /**
     * 补充 是否有科目未配置标签
     *
     * @param resList 数据列表
     */
    public void supplyExistUnConfigCourse(List<BankRuleRes> resList)
    {
        if (CollectionUtil.isEmpty(resList)) {
            return;
        }
        List<BankRule> differentTestConfModeTypeRuleList = resList.stream()
                .filter(BankRule::hasCourseChildrenRule)
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(differentTestConfModeTypeRuleList)) {
            return;
        }
        List<Long> courseIdList = differentTestConfModeTypeRuleList
                .stream().map(BankRule::getCourseParentId)
                .collect(Collectors.toList());

        List<Course> courseList = courseService.list(new LambdaQueryWrapper<Course>()
                .in(Course::getParentId, courseIdList));
        Map<Long, Integer> childrenAmountGroupByCourseId
                = courseList
                .stream()
                .collect(Collectors.groupingBy(Course::getParentId,
                        Collectors.collectingAndThen(Collectors.toList(), List::size)));
        Integer childrenAmount;
        for (BankRuleRes res : resList) {
            if ((RuleConst.ConfModeType.UNIFY.getCode().equals(res.getTestConfModeTypeCode())
                    && RuleConst.ConfModeType.UNIFY.getCode().equals(res.getPracticeConfModeTypeCode()))) {
                continue;
            }

            childrenAmount = childrenAmountGroupByCourseId.get(res.getCourseParentId());
            res.setExistUnConfigCourse(CollectionUtil.isNotEmpty(res.getChildren())
                    && childrenAmount > res.getChildren().size());
        }
    }

    /**
     * 补充下级课程信息列表
     *
     * @param resList 结果列表
     */
    public void supplyBatchChildren(List<BankRuleRes> resList)
    {
        if (CollectionUtil.isEmpty(resList)) {
            return;
        }
        // 获取下一级规则id信息
        List<Long> parentIdList
                = resList.stream().map(BankRuleRes::getId).collect(Collectors.toList());
        BankRuleDo bankRuleDo = new BankRuleDo();
        bankRuleDo.setTypeCode(RuleConst.Type.SINGLE.getCode());
        bankRuleDo.setParentIdList(parentIdList);
        Map<Long, List<BankRuleRes>> childrenGroupByParentId = service.listPoByDo(bankRuleDo)
                .stream()
                .map(po -> BeanUtil.toBean(po, BankRuleRes.class))
                .collect(Collectors.groupingBy(BankRule::getParentId));
        for (BankRuleRes res : resList) {
            if (childrenGroupByParentId.containsKey(res.getId())) {
                res.setChildren(childrenGroupByParentId.get(res.getId()));
            }
        }
    }
}
